﻿using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

public class XmlSerializer<T>
{
    #region Properties

    private T source;

    #endregion

    public XmlSerializer(T source)
    {
        this.source = source;
    }

    #region Methods

    /// <summary>
    /// Parses the current status of the source object to an xml string.
    /// </summary>
    /// <returns>An string with the xml file.</returns>
    public virtual string GetXml()
    {
        return XmlSerializer.GetXml(this.source);
    }
    //public T Load(string fileName)
    //{
    //    System.Xml.Serialization.XmlSerializer mySerializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
    //    FileStream myFileStream = new FileStream(fileName, FileMode.Open);
    //    T obj = (T)mySerializer.Deserialize(myFileStream);
    //    myFileStream.Dispose();

    //    return obj;
    //}
    public virtual void Save(string fileName)
    {
        XmlSerializer.Save<T>(fileName, this.source);
    }

    #endregion
}

public static class XmlSerializer
{
    #region Static Methods

    /// <summary>
    /// Parses the object specified to an xml string.
    /// </summary>
    /// <returns>An string with the xml file.</returns>
    public static string GetXml(object obj)
    {
        MemoryStream ms = new MemoryStream();

        //XmlTextWriter xmlWriter;
        //xmlWriter = new XmlTextWriter(ms, Encoding.UTF8);

        /* Creates our own namespaces for the output. */
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

        /* Adds an empty namespace and empty value. */
        ns.Add("", "");

        /* Configures the xml writer. */
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.OmitXmlDeclaration = true;
        settings.Encoding = new UTF8Encoding(false);
        settings.Indent = true;
        settings.IndentChars = "    ";
        settings.NewLineHandling = NewLineHandling.Replace;
        settings.NewLineChars = "\r\n";
        settings.NewLineOnAttributes = true;

        /* Creates xml with the object to serrialize. */
        XmlWriter xml = XmlWriter.Create(ms, settings);

        System.Xml.Serialization.XmlSerializer mySerializer =
            new System.Xml.Serialization.XmlSerializer(obj.GetType());

        mySerializer.Serialize(xml, obj, ns);

        /* Returns the xml string with the object serialized. */
        return Encoding.UTF8.GetString(ms.GetBuffer());
    }
    public static T LoadFromXmlString<T>(string xml)
    {
        //Returns an instance of the type serialized.
        return (T)XmlSerializer.LoadFromXmlString(xml, typeof(T));
    }
    public static object LoadFromXmlString(string xml, Type type)
    {
        /* Initializes XmlSerializer with the type of this class. */
        System.Xml.Serialization.XmlSerializer mySerializer = new System.Xml.Serialization.XmlSerializer(type);

        StringReader stringReader = new StringReader(xml);

        XmlReader xmlReader = XmlReader.Create(stringReader);

        /* Returns an instance of the type serialized. */
        return mySerializer.Deserialize(xmlReader);
    }
    public static T LoadFromFile<T>(string fileName)
    {
        return (T)XmlSerializer.LoadFromFile(fileName, typeof(T));
    }
    public static object LoadFromFile(string fileName, Type type)
    {
        System.Xml.Serialization.XmlSerializer mySerializer = new System.Xml.Serialization.XmlSerializer(type);
        FileStream myFileStream = new FileStream(fileName, FileMode.Open);

        object objLoaded = mySerializer.Deserialize(myFileStream);

        myFileStream.Dispose();

        return objLoaded;
    }
    public static void Save<T>(string fileName, T obj)
    {
        XmlSerializer.Save(fileName, obj, typeof(T));
    }
    public static void Save(string fileName, object obj, Type type)
    {
        System.Xml.Serialization.XmlSerializer mySerializer = new System.Xml.Serialization.XmlSerializer(type);
        StreamWriter myWriter = new StreamWriter(fileName);

        mySerializer.Serialize(myWriter, obj);

        myWriter.Dispose();
    }

    #endregion
}